package com.globalwave.common.web;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;

import com.globalwave.base.BaseAction;
import com.globalwave.common.ArrayPageList;
import com.globalwave.common.C;
import com.globalwave.common.ImageUtil;
import com.globalwave.common.entity.File;
import com.globalwave.common.entity.FileCriterion;
import com.globalwave.common.service.FileService;
import com.opensymphony.xwork2.Preparable;

public class FileAction extends BaseAction implements Preparable {

    private static final long serialVersionUID = 8582051849254108462L;
    
    private FileService fileService ;
    private File file ;
    private Long user_id ;
    private Long organization_id ;
    private Long[] file_ids ;
    private FileCriterion fileCriterion ; 
    
    public String execute() throws Exception {    
        return this.list();
    }
    
    public String list() throws Exception {      
        
        ArrayPageList<File> pageList = 
            fileService.query(fileCriterion,pageIndex,pageSize,null) ;

        renderXML(pageList.asXML()) ;
        
        return null ;    
        
    }
    public String downLoadMiniJpg() throws Exception {
        // temp\ref_type\[s.]file_name.file_type
        String fileName = getDownLoadFileName() ;
        
        java.io.File f = new java.io.File(fileName + ".mjpg") ;
        
        if (!f.exists()) {
            // get file from database
            FileUtils.forceMkdir(new java.io.File(getDownLoadDirName())) ;
            java.io.File dbFile = fileService.get(this.file.getFile_id()) ; 
            f = new java.io.File(fileName) ;
            f.createNewFile() ;
            FileUtils.copyFile(dbFile, f) ;
            FileUtils.forceDelete(dbFile) ;
            
            ImageUtil.getFixedBoundIcon(f, 120, 120) ;
        }
        
        outputFile(fileName, f);

        return null ;
    }

    private void outputFile(String fileName, java.io.File f) throws IOException, FileNotFoundException {
        int length;
        HttpServletResponse resp = this.getResponse() ;
        ServletOutputStream op = resp.getOutputStream();
        ServletContext context  = this.getServletContext();
        String mimetype = context.getMimeType( fileName );

        //
        //  Set the response and go!
        //
        //
        resp.setContentType( (mimetype != null) ? mimetype : "application/octet-stream" );
        resp.setContentLength( (int)f.length() );
        resp.setHeader( "Content-Disposition", "attachment; filename=\"" + this.file.getFile_id() + "\"" );

        //
        //  Stream to the requester.
        //
        byte[] bbuf = new byte[1024];
        DataInputStream in = new DataInputStream(new FileInputStream(f));

        while ((in != null) && ((length = in.read(bbuf)) != -1))
        {
            op.write(bbuf,0,length);
        }

        in.close();
        op.flush();
        op.close();
    }
    
    public String downLoadFile() throws Exception {
        // temp\ref_type\[s.]file_name.file_type
        String fileName = getDownLoadFileName() ;
        
        java.io.File f = new java.io.File(fileName ) ;
        
        if (!f.exists()) {
            // get file from database
            FileUtils.forceMkdir(new java.io.File(getDownLoadDirName())) ;
            java.io.File dbFile = fileService.get(this.file.getFile_id()) ; 
            f = new java.io.File(fileName) ;
            f.createNewFile() ;
            FileUtils.copyFile(dbFile, f) ;
            FileUtils.forceDelete(dbFile) ;
        }
        
        outputFile(fileName, f);

        return null ;
    }
    
    public String create()  throws Exception {
        Object newFile = fileService.create(file) ;

        renderXML(this.getSuccessCreateMessage(newFile).asXML()) ;
        
        return null;    
        
    }
    
    public String update()  throws Exception {     
        
        fileService.update(file) ;

        renderXML(this.getSuccessUpdateMessage(file).asXML()) ;
        
        return null;    
        
    }
    
    public String delete()  throws Exception {
        if (this.file_ids == null) { 
            fileService.delete(file) ;
        } else {
            fileService.deleteAll(this.file_ids) ;
        }

        renderXML(this.getSuccessDeleteMessage().asXML()) ;
        
        return null;    
        
    }

    public void prepare() throws Exception {
        // TODO Auto-generated method stub
        
    }
    
    public String getDownLoadFileName() {
        return C.TEMP_DOWNLOAD_DIR 
                   + "/" + this.file.getReference_type()
                   + "/" + this.file.getReference_id() 
                   + "/" + this.file.getFile_id() ;
    }
    
    public String getDownLoadDirName() {
        return C.TEMP_DOWNLOAD_DIR 
                   + "/" + this.file.getReference_type()
                   + "/" + this.file.getReference_id();
    }
    
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public FileCriterion getFileCriterion() {
        return fileCriterion;
    }

    public void setFileCriterion(FileCriterion fileCriterion) {
        this.fileCriterion = fileCriterion;
    }

    public Long getUser_id() {
        return user_id;
    }

    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }

    public Long getOrganization_id() {
        return organization_id;
    }

    public void setOrganization_id(Long organization_id) {
        this.organization_id = organization_id;
    }

    public void setFile_ids(Long[] file_ids) {
        this.file_ids = file_ids;
    }
}
